package com.tianyi.menu;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.tianyi.dao.entity.menu.Menu;
import com.tianyi.dao.entity.menu.MenuExample;
import com.tianyi.dao.entity.sysUser.SysUser;
import com.tianyi.dao.mapper.MenuMapper;
import com.tianyi.lib.enums.SysUserTypes;
import com.tianyi.lib.model.WebResult;
import com.tianyi.lib.req.MenuReq;
import com.tianyi.lib.result.GenerateBaseMenuResult;
import com.tianyi.role.RoleService;
import com.tianyi.sysUser.SysUserService;
import com.tianyi.vo.PullDownVO;
import com.tianyi.vo.menu.MenuBean;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 *
 * @author cuixuhui
 */
@Service
public class MenuService {

    private static Logger logger = LoggerFactory.getLogger(MenuService.class);

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private RoleService roleService;

    public WebResult<?> loadMenu(Long empId){

        SysUser sysUser = sysUserService.queryUserByEmpId(empId);
        if (sysUser == null){

            return WebResult.error("user empId="+empId+" is not exist db");
        }

        String pmsTypeStr = sysUser.getUserType();

        //todo 用户load取菜单
        Long roleId = sysUser.getRoleId();
        if (Objects.isNull(roleId)){

        }
        List<Long> menuIds = roleService.getMenuIdsByRoleId(roleId);
        List<Menu> menus = this.queryMenusByIds(menuIds);
        //获取所有菜单
        if (SysUserTypes.ADMIN.name().equals(pmsTypeStr)){
            menus = queryAllMenus();
        }
        if (CollectionUtils.isEmpty(menus)){

        }

        List<MenuBean> menuBeans = menus.stream().map(ret -> {
            MenuBean menuBean = new MenuBean();
            BeanUtils.copyProperties(ret, menuBean);
            return menuBean;
        }).collect(Collectors.toList());
        //父id
        List<MenuBean> parentMenuBean = menuBeans.stream().filter(ret -> Objects.isNull(ret.getParentId())).collect(Collectors.toList());

        Map<Long, List<MenuBean>> childMenusMap = menuBeans.stream().filter(ret -> Objects.nonNull(ret.getParentId())).collect(Collectors.groupingBy(MenuBean::getParentId));
        for (MenuBean menuBean : menuBeans) {
            Long id = menuBean.getId();
            List<MenuBean> childMenus = childMenusMap.get(id);
            if (Objects.isNull(menuBean)){
                continue;
            }
            menuBean.setChildren(childMenus);
        }
        return WebResult.ok(parentMenuBean);
    }

    public WebResult<String> preCheck(MenuReq req){

        if (StringUtils.isBlank(req.getTitle())){
            return WebResult.error("菜单名为空");
        }
//        if (StringUtils.isBlank(req.getIcon())){
//            return WebResult.error("图标icon");
//        }
//        if (StringUtils.isBlank(req.getUrl())){
//            return WebResult.error("url资源为空");
//        }
        if (Objects.nonNull(req.getParentId())){
            Menu menu = menuMapper.selectByPrimaryKey(req.getParentId());
            if (Objects.isNull(menu)){
                return WebResult.error("父菜单为空");
            }
        }

        MenuExample example = new MenuExample();
        example.or().andTitleEqualTo(req.getTitle());
        if (StringUtils.isNotBlank(req.getUrl())){
            example.or().andUrlEqualTo(req.getUrl());
        }

        List<Menu> menus = menuMapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(menus)){
            List<Menu> menuList = menus.stream().filter(ret -> !Objects.equals(ret.getId(), req.getId())).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(menuList)){
                return WebResult.error("菜单名/菜单url重复");
            }
        }
        return WebResult.ok("success");
    }

    private Menu gentMenuByReq(MenuReq req){

        return gentMenu(new Menu(), req);
    }

    private Menu gentMenu(Menu menu, MenuReq req){

        if (Objects.isNull(menu) || Objects.isNull(req)){
            return null;
        }
        if (Objects.isNull(req.getId())){
            menu.setGmtCreate(new Date());
        }
        menu.setGmtModified(new Date());
        menu.setTitle(req.getTitle());
        menu.setIcon(req.getIcon());
        menu.setUrl(req.getUrl());
        menu.setParentId(req.getParentId());
        return menu;
    }

    public WebResult<String> addMenu(MenuReq req) {

        WebResult<String> preCheck = preCheck(req);
        if (!preCheck.isSuccess()){
            return preCheck;
        }

        Menu menu = gentMenuByReq(req);
        menuMapper.insert(menu);
        return WebResult.ok("success");
    }

    public WebResult<String> deleteMenu(MenuReq req) {

        if (Objects.isNull(req.getId())){
            return WebResult.error("菜单id为空");
        }
        menuMapper.deleteByPrimaryKey(req.getId());
        return WebResult.ok("success");
    }

    public WebResult<?> updateMenu(MenuReq req) {

        Long id = req.getId();
        if (id == null) {
            return WebResult.error("update menu id is null");
        }
        WebResult<String> preCheck = preCheck(req);
        if (!preCheck.isSuccess()){
            return preCheck;
        }
        Menu menu = menuMapper.selectByPrimaryKey(id);
        if (Objects.isNull(menu)){
            return WebResult.error("修改菜单不存在");
        }
        Menu updateMenu = gentMenu(menu, req);
        menuMapper.updateByPrimaryKey(updateMenu);

        return WebResult.ok("success");
    }

    public WebResult<?> queryMenuPage(MenuReq req) {

        MenuExample example = new MenuExample();
        example.setOrderByClause("id DESC");
        MenuExample.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(req.getTitle())){
            criteria.andTitleEqualTo(req.getTitle());
        }
        if (StringUtils.isNotBlank(req.getUrl())){
            criteria.andUrlLike(req.getUrl());
        }
        Page<Menu> menuPage = menuMapper.selectByExample(example, new RowBounds(req.getPageNo(), req.getPageSize()));

        PageInfo<Menu> menuPageInfo = menuPage.toPageInfo();
        return WebResult.ok(menuPageInfo);
    }

    /**
     * 获取菜单下拉
     * @return
     */
    public WebResult<List<PullDownVO>> getMenuPullDown() {

        MenuExample example = new MenuExample();
        List<Menu> menus = menuMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(menus)){

            return WebResult.ok(Lists.newArrayList());
        }
        List<PullDownVO> vos = ListUtils.emptyIfNull(menus).stream().map(ret -> {
            PullDownVO vo = new PullDownVO();
            vo.setLabel(ret.getTitle());
            vo.setValue(ret.getId());
            return vo;
        }).collect(Collectors.toList());
        return WebResult.ok(vos);
    }

    public List<Menu> queryMenusByIds(List<Long> menuIds) {

        if (CollectionUtils.isEmpty(menuIds)){
            return new ArrayList<>();
        }
        MenuExample example = new MenuExample();
        example.createCriteria().andIdIn(menuIds);
        List<Menu> menus = menuMapper.selectByExample(example);
        return menus;
    }

    public List<Menu> queryAllMenus() {

        MenuExample example = new MenuExample();
        List<Menu> menus = menuMapper.selectByExample(example);
        return menus;
    }

    public WebResult<Object> loadMenuNewByRoleId(Long roleId) {
        List<Long> menuIds;
        if(roleId==null || roleId<1){
            return WebResult.error("INVALID ROLEID");
        }
        try {
            menuIds = roleService.getMenuIdsByRoleId(roleId);
            System.out.println("menuIds "+menuIds);
        }catch(Exception e){
            return WebResult.error("ERROR WHEN QUERY FROM DATABASE");
        }
        return WebResult.ok(GenerateBaseMenuResult.generateByKeys(menuIds));
    }

    public WebResult<Object> loadMenuNewByEmpId(Long empId){
        SysUser sysUser;
        try {
            sysUser = sysUserService.queryUserByEmpId(empId);
        }catch(Exception e){
            return WebResult.error("ERROR WHEN QUERY FROM DATABASE");
        }
        if (sysUser == null){
            return WebResult.error("user empId="+empId+" is not exist db");
        }

        //todo 用户load取菜单
        Long roleId = sysUser.getRoleId();
        if(roleId==null || roleId<1){
            return WebResult.error("INVALID ROLEID");
        }
        List<Long> menuIds;
        try {
            menuIds = roleService.getMenuIdsByRoleId(roleId);
        }catch(Exception e){
            return WebResult.error("ERROR WHEN QUERY FROM DATABASE");
        }
        return WebResult.ok(GenerateBaseMenuResult.generateByKeys(menuIds));
    }
}
